package com.ymt.bpm.service.platform.fauth.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ymt.bpm.dao.MDao;
import com.ymt.bpm.dao.Mapper;
import com.ymt.bpm.engine.EngineConst;
import com.ymt.bpm.model.Const.Oplog;
import com.ymt.bpm.model.PUser;
import com.ymt.bpm.model.PUserExt;
import com.ymt.bpm.model.PUserExtref;
import com.ymt.bpm.service.platform.fauth.FaUserService;
import com.ymt.bpm.service.platform.log.OpLogService;
import com.ymt.bpm.util.Const;
import com.ymt.bpm.util.DateUtil;
import com.ymt.bpm.util.DhxUtil;
import com.ymt.bpm.util.EncodeUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Created by Johnny on 2017/2/17.
 */
@Service
public class FaUserServiceImpl implements FaUserService {

    @Autowired
    private MDao mDao;

    private String mapperExtRef = "PUserExtrefMapper";

    @Autowired
    private OpLogService oplog;

    @Override
    public JSONObject allByTenant(String tenantId,
                                 String queryParams,
                                 int timezoneOffset) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        if (queryParams!=null && queryParams.length()>0) {
            paramMap.putAll(JSONObject.parseObject(queryParams));
        }
        paramMap.put(Const.TENANT_ID, tenantId);
        if (paramMap.containsKey("search") && paramMap.get("search")!=null) {
            paramMap.put("search", EncodeUtil.decode((String)paramMap.get("search")));
        }
        int offset = (int)paramMap.get("offset");
        List<Map<String, Object>> list = mDao.selectList(Mapper.PUserMapper, "selectAllByTenant", paramMap);
        int total = mDao.selectOne(Mapper.PUserMapper, "selectAllByTenantCount", paramMap);
        JSONObject rtn = new JSONObject();
        JSONArray rows = new JSONArray();
        if (list!=null && list.size()>0) {
            for (Map<String, Object> user : list) {
                JSONObject node = DhxUtil.toJsonWithDateAli(user, Const.LANG_ZH, timezoneOffset, true);
                node.remove("password");
                node.put("_ITEM_NO", ++offset);
                rows.add(node);
            }
        }
        rtn.put("rows", rows);
        rtn.put("total", total);
        return rtn;
    }

    @Override
    public JSONObject listAll(String tenantId, String search, String sort,
                              String order, int offset, int limit) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put(Const.TENANT_ID, tenantId);
        paramMap.put("search", search);
        paramMap.put("sort", sort);
        paramMap.put("order", order);
        PageHelper.offsetPage(offset, limit);
        List<Map<String, Object>> list = mDao.selectList("PUserMapper", "listAll", paramMap);
        JSONObject rtn = new JSONObject();
        PageInfo pageInfo = new PageInfo(list);
        if (list!=null && list.size()>0) {
            for (Map<String, Object> row : list) {
                row.remove("PASSWORD");
                row.put("_ITEM_NO", ++offset);
            }
        }
        rtn.put("rows", list);
        rtn.put("total", pageInfo.getTotal());
        return rtn;
    }

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    public JSONObject saveDetailed(String tenantId,
                                   String loginName,
                                   String displayName,
                                   PUser user,
                                   PUserExt userExt,
                                   PUserExtref userExtref) {
        if (tenantId!=null) {
            user.setTenantId(Integer.parseInt(tenantId));
            userExt.setTenantId(Integer.parseInt(tenantId));
            userExtref.setTenantId(Integer.parseInt(tenantId));
        }
        int rs = 0;

        user.setDisplayName(user.getRealName()+"("+user.getLoginName()+")");    //both used in insert and update

        if (user.getUserId()==null || user.getUserId().length()==0) {
            user.setUserId(user.getLoginName());
            user.setStatus("10");
            user.setUserNumber(user.getLoginName());
            user.setLang(Const.LANG_ZH);
            userExt.setUserId(user.getLoginName());
            userExt.setCreator(loginName);
            userExt.setCreatorName(displayName);
            userExt.setCreateTime(DateUtil.getGMTDate());
            user.setPassword(DigestUtils.sha256Hex(user.getPassword()));
            rs += mDao.insert("PUserMapper", "insertSelective", user);
            rs += mDao.insert("PUserExtMapper", "insertSelective", userExt);
            if (userExtref.getRefUser()!=null && userExtref.getRefUser().length()>0) {
                userExtref.setId("REF-"+ UUID.randomUUID().toString());
                userExtref.setUserId(user.getUserId());
                userExtref.setUserName(user.getDisplayName());
                rs += mDao.insert(mapperExtRef, "insertSelective", userExtref);
            }

            //记录日志
            oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.CREATE, Oplog.CODE.USER, user.getLoginName() + " - " + user.getDisplayName());

        } else {
            userExt.setUpdator(loginName);
            userExt.setUpdatorName(displayName);
            rs += mDao.update("PUserMapper", "updateByPrimaryKeySelective", user);
            rs += mDao.update("PUserExtMapper", "updateByPrimaryKeySelective", userExt);
            //delete and insert
            rs += mDao.delete(mapperExtRef, "deleteByUserId", userExtref);
            if (userExtref.getRefUser()!=null && userExtref.getRefUser().length()>0) {
                userExtref.setId("REF-" + UUID.randomUUID().toString());
                userExtref.setUserId(user.getUserId());
                userExtref.setUserName(user.getDisplayName());
                rs += mDao.insert(mapperExtRef, "insertSelective", userExtref);
            }

            //记录日志
            oplog.bizlog(tenantId, loginName, displayName, null, Oplog.OP.UPDATE, Oplog.CODE.USER, user.getLoginName() + " - " + user.getDisplayName());
        }
        JSONObject rtn = new JSONObject();
        rtn.put("result", rs);
        return rtn;
    }
}
